package com.zz.framework.core.base

import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.AnimationDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.RelativeLayout
import android.widget.TextView
import com.zz.framework.core.ext.*
import com.zz.framework.core.utils.IntentBuilder.Companion.EXTRA_ADD_BACK_BUTTON
import com.zz.framework.core.utils.IntentBuilder.Companion.EXTRA_HAS_TITLE
import com.zz.framework.core.utils.LogUtils
import com.zz.framework.core.view.BaseUIFactory
import com.zz.framework.core.view.BaseUIProvider
import com.zz.framework.core.view.SimpleBaseUIFactory
import com.zz.framework.R
import com.zz.framework.databinding.ActivityWithToolbarLayoutBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel

/**
 * Copyright © 2019 zanezhao All rights reserved.
 * Created by zanezhao on 2019-11-13 15:28.
 * @author: zanezhao 1820022519@qq.com
 * @version: V1.0
 */
open abstract class BaseUIActivity : BaseActivity(), CoroutineScope by MainScope() {

    open fun onAttach() {}

    abstract fun initView()

    abstract fun initData()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBaseAttribute = BaseAttribute()
        onInitAttribute(mBaseAttribute)
        initContentView()
        initContentAttribute()
        onAttach()
        initView()
        initData()
    }

    override fun onResume() {
        super.onResume()
        ("activity---->" + this.javaClass.simpleName).print()
    }

    private fun initContentAttribute() {
        if (mBaseAttribute.mHasTitle) {
            initBaseUIFactory()
            mRelativeLayoutTitle = findViewById(mBaseAttribute.mTitleLayoutId)
            if (mBaseAttribute.mAddBackButton) {
                mButtonBack = onCreateBackButton()
                if (mButtonBack != null) {
                    mButtonBack?.onClick(block = {
                        onBackPressed()
                    })
                    mRelativeLayoutTitle?.addView(mButtonBack, onCreateBackButtonLayoutParams()!!)
                }
            }
            if (mBaseAttribute.mAddTitleText) {
                if (mBaseAttribute.mTitleText == null) {
                    addTextInTitle(mBaseAttribute.mTitleTextStringId)
                } else {
                    addTextInTitle(mBaseAttribute.mTitleText!!)
                }
            }
            mBaseUIFactory?.onTitleCreated(this, mButtonBack, mTextViewTitle!!)

            mBaseUIFactory?.let {
                it.titleBackagegroundColorRes?.let {
                    if (it > 0) {
                        mRelativeLayoutTitle?.setBackgroundColor(resources.getColor(it))
                    }
                }
                it.titleBackagegroundDrawbleRes?.let {
                    if (it > 0) {
                        mRelativeLayoutTitle?.setBackgroundResource(it)
                    }
                }
            }
        } else {
            val v: View? = findViewById(mBaseAttribute.mTitleLayoutId)
            v?.setVisibility(View.GONE)
        }
        initProgressLayout()
    }

    var mProgressView: View? = null
    protected fun initProgressLayout() {
        if (mProgressView == null) {
            mProgressView = layoutInflater.inflate(R.layout.loading_layout, window.decorView as ViewGroup?, false)
            mProgressView?.setOnClickListener({ _: View? -> })
            (window.decorView as ViewGroup?)?.addView(mProgressView)
            dismissProgress()
        }
    }

    private var mViewPromptConnection: View? = null
    private var mViewConnecting: View? = null
    private var mViewNormal: View? = null
    private var mImageViewPromptConnection: ImageView? = null
    protected fun addConnectionPromptView() {
        if (mViewPromptConnection == null) {
            mViewPromptConnection = layoutInflater.inflate(
                R.layout.prompt_connection,
                window.decorView as ViewGroup?,
                false
            )
            mViewConnecting = mViewPromptConnection?.findViewById(R.id.viewConnecting)
            mViewNormal = mViewPromptConnection?.findViewById(R.id.viewNormal)
            mViewConnecting?.gone()
            mViewNormal?.visible()
            addContentView(
                mViewPromptConnection,
                ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT
                )
            )
        } else {
            mViewPromptConnection?.setVisibility(View.VISIBLE)
        }
        startUnConnectionAnimation()
    }

    protected fun removeConnectionPromptView() {
        if (mViewPromptConnection != null) {
            mViewPromptConnection?.gone()
        }
    }

    protected open fun startUnConnectionAnimation() {
        if (mViewPromptConnection != null && mViewNormal!!.visibility == View.VISIBLE) {
            mImageViewPromptConnection =
                mViewPromptConnection!!.findViewById<View>(R.id.iv) as ImageView
            mImageViewPromptConnection?.setBackgroundDrawable(null)
            mImageViewPromptConnection?.setBackgroundResource(R.drawable.animlist_prompt_connection)
            val d = mImageViewPromptConnection?.getBackground() as AnimationDrawable
            d.start()
        }
    }

    fun showProgress(progress: Float = -1f) {
        val loadingView = mProgressView?.findViewById<ProgressBar>(R.id.loadingView)
        loadingView?.visible()
        mProgressView?.visible()
    }

    fun dismissProgress() {
        mProgressView?.findViewById<ProgressBar>(R.id.loadingView)?.visible()
        mProgressView?.gone()
        LogUtils.error("dismissProgress")
    }
    lateinit var toolbarBinding: ActivityWithToolbarLayoutBinding
    //XxActivity -> activity_xx_layout
    private fun initContentView() {
        if (mBaseAttribute.mContentLayoutId == 0 && mBaseAttribute.mSetContentView) {
            val strClassName = this.javaClass.name
            val nIndex = strClassName.lastIndexOf(".")
            if (nIndex != -1) {
                val cName = strClassName.substring(nIndex + 1)
                var strResourceName = "activity" + cName.replaceFirst("Activity".toRegex(), "")
                strResourceName = strResourceName.camelToUnderline()
                var nLayoutId = resources.getIdentifier(strResourceName, "layout", this.packageName)
                if (nLayoutId != 0) {
                    mBaseAttribute.mContentLayoutId = nLayoutId
                } else {
                    strResourceName += "_layout"
                    nLayoutId = resources.getIdentifier(strResourceName, "layout", this.packageName)
                    mBaseAttribute.mContentLayoutId = nLayoutId
                }
            }
        }
        if (mBaseAttribute.mContentLayoutId != 0) {
            if (mBaseAttribute.mHasTitle) {
                toolbarBinding = ActivityWithToolbarLayoutBinding.inflate(layoutInflater)
                setContentView(toolbarBinding.root)
                var view: View = getLayoutInflater().inflate(mBaseAttribute.mContentLayoutId, null, false)
                toolbarBinding.mContentLayout.addView(view)
            } else {
                setContentView(mBaseAttribute.mContentLayoutId)
            }
        } else {
            throw Throwable("layout must set")
        }
    }

    protected fun onCreateBackButton(): View? {
        return mBaseUIFactory?.createTitleBackButton()
    }

    protected fun addTextInTitle(nResId: Int) {
        mTextViewTitle = onCreateTitleTextView(nResId)
        mRelativeLayoutTitle?.addView(mTextViewTitle, onCreateTitleTextViewLayoutParams())
    }

    protected fun addTextInTitle(strText: String) {
        mTextViewTitle = onCreateTitleTextView(strText)
        mRelativeLayoutTitle?.addView(mTextViewTitle, onCreateTitleTextViewLayoutParams())
    }

    protected fun onCreateTitleTextView(nResId: Int): TextView? {
        val textView = LayoutInflater.from(this).inflate(
            mBaseAttribute.mTitleTextLayoutId,
            null
        ) as TextView
        try {
            textView.setText(nResId)
        } catch (e: Exception) {
        }

        return textView
    }

    protected fun onCreateTitleTextView(strText: String): TextView {
        val textView = LayoutInflater.from(this).inflate(
            mBaseAttribute.mTitleTextLayoutId,
            null
        ) as TextView
        textView.text = strText
        return textView
    }

    protected fun onCreateTitleTextViewLayoutParams(): RelativeLayout.LayoutParams {
        return RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.MATCH_PARENT
        )
    }

    protected fun onCreateBackButtonLayoutParams(): RelativeLayout.LayoutParams {
        val lp = RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.MATCH_PARENT
        )
        lp.leftMargin = mBaseUIFactory?.titleBackButtonLeftMargin ?: 0
        lp.topMargin = mBaseUIFactory?.titleBackButtonTopMargin ?: 0
        lp.bottomMargin = mBaseUIFactory?.titleBackButtonBottomMargin ?: 0
        lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
        return lp
    }

    protected fun addSubTitle(): TextView {
        mTextViewTitle?.setPadding(
            mTextViewTitle!!.getPaddingLeft(),
            mTextViewTitle!!.getPaddingTop(),
            mTextViewTitle!!.getPaddingRight(),
            15.dp2px()
        )
        val textViewSubTitle =
            LayoutInflater.from(this).inflate(R.layout.textview_subtitle, null) as TextView
        mRelativeLayoutTitle?.addView(
            textViewSubTitle,
            RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT,
                RelativeLayout.LayoutParams.MATCH_PARENT
            )
        )
        textViewSubTitle.setPadding(
            textViewSubTitle.paddingLeft,
            24.dp2px(),
            textViewSubTitle.paddingRight,
            textViewSubTitle.paddingBottom
        )
        //设置阴影
        textViewSubTitle.setShadowLayer(1f, 0f, -2f, Color.parseColor("#171717"))
        mTextViewSubTitle = textViewSubTitle
        return mTextViewSubTitle!!
    }

    protected fun addImageButtonInTitleRight(resId: Int): View? {
        return if (mBaseUIFactory != null) {
            addViewInTitleRight(
                mBaseUIFactory!!.createTitleRightImageButton(resId),
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                mBaseUIFactory?.titleRightImageButtonTopMargin ?: 0,
                mBaseUIFactory?.titleRightImageButtonRightMargin ?: 0
            )
        } else null
    }

    protected fun addTextButtonInTitleRight(textId: Int): View? {
        return if (mBaseUIFactory != null) {
            addViewInTitleRight(
                mBaseUIFactory!!.createTitleRightTextButton(textId),
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.MATCH_PARENT,
                mBaseUIFactory?.titleRightTextButtonTopMargin ?: 0,
                mBaseUIFactory?.titleRightTextButtonRightMargin ?: 0
            )
        } else null
    }

    protected fun addTextButtonInTitleRight(text: String): View? {
        return if (mBaseUIFactory != null) {
            addViewInTitleRight(
                mBaseUIFactory!!.createTitleRightTextButton(text),
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.MATCH_PARENT,
                mBaseUIFactory?.titleRightTextButtonTopMargin ?: 0,
                mBaseUIFactory?.titleRightTextButtonRightMargin ?: 0
            )
        } else null
    }

    val rightButtonList = mutableListOf<View>()
    fun removeAllRightButton(){
        rightButtonList.forEachIndexed { index, view ->
            run {
                mRelativeLayoutTitle?.removeView(view)
            }
        }
        rightButtonList.clear()
    }

    protected fun addViewInTitleRight(
        v: View,
        width: Int,
        height: Int,
        nTopMargin: Int,
        nRightMargin: Int
    ): View {
        val lp = RelativeLayout.LayoutParams(width, height)
        lp.topMargin = nTopMargin
        lp.rightMargin = nRightMargin
        lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
        mRelativeLayoutTitle?.addView(v, lp)
        v.onClick {
            onTitleRightButtonClicked(it)
        }
        rightButtonList.add(v)
        return v
    }

    protected open fun onTitleRightButtonClicked(v: View) {

    }


    protected fun startActivity(clazz: Class<*>, name: String, value: Boolean) {
        val intent = Intent(this, clazz).putExtra(name, value)
        startActivity(intent)
    }

    override fun onDestroy() {
        cancel()
        super.onDestroy()
    }


    private var mBaseUIFactory: BaseUIFactory? = null
    protected lateinit var mBaseAttribute: BaseAttribute
    private var mRelativeLayoutTitle: RelativeLayout? = null
    private var mButtonBack: View? = null
    protected var mTextViewTitle: TextView? = null
    private var mTextViewSubTitle: TextView? = null

    protected fun updateTitle(title: String?) {
        mTextViewTitle?.setText(title ?: "")
    }

    open protected fun onInitAttribute(ba: BaseAttribute) {
        if (intent.hasExtra(EXTRA_HAS_TITLE)) {
            ba.mHasTitle = intent.getBooleanExtra(EXTRA_HAS_TITLE, true)
        }
        if (intent.hasExtra(EXTRA_ADD_BACK_BUTTON)) {
            ba.mAddBackButton = intent.getBooleanExtra(EXTRA_ADD_BACK_BUTTON, false)
        }
        ba.mTitleLayoutId = R.id.viewTitle
        ba.mTitleTextLayoutId = R.layout.textview_title
    }

    protected fun initBaseUIFactory() {
        if (mBaseUIFactory == null) {
            val c = BaseUIProvider.baseUIFactoryClass
            if (c == null) {
                mBaseUIFactory = SimpleBaseUIFactory(this)
            } else {
                try {
                    val constructor = c!!.getDeclaredConstructor(Context::class.java)
                    mBaseUIFactory = constructor.newInstance(this) as BaseUIFactory
                } catch (e: Exception) {
                    e.printStackTrace()
                    mBaseUIFactory = SimpleBaseUIFactory(this)
                }
            }
        }
    }

    protected class BaseAttribute {
        var mSetContentView = true
        var mContentLayoutId: Int = 0
        var mHasTitle = true
        var mTitleLayoutId: Int = 0
        var mAddTitleText = true
        var mTitleTextLayoutId: Int = 0
        var mTitleTextStringId: Int = R.string.app_name
        var mTitleText: String? = null
        var mAddBackButton = true
    }


}
